package multiclient;



//Set up a Server that will receive a connection
//from a client, send a string to the client,
//and close the connection.

//Java core packages
import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.awt.*;
import java.awt.event.*;
//Java extension packages
import javax.swing.*;
public class Server3 extends JFrame {
	private static JTextField enterField;
	private static JTextArea displayArea;
	private static ServerSocket server;	
	protected static int counter = 0;
	protected static Multi[] m = new Multi[10]; 
	// set up GUI
	public Server3()
	{
		super( "Server" );

		Container container = getContentPane();

		// create enterField and register listener
		enterField = new JTextField();
		enterField.setEnabled( false );
		container.add( enterField, BorderLayout.NORTH );

		// create displayArea
		displayArea = new JTextArea();
		container.add( new JScrollPane( displayArea ),
				BorderLayout.CENTER );
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setSize( 400, 250 );
		setVisible( true );
	}
	// execute application
	public static void main( String args[] ) throws IOException
	{
	new Server3();
		server = new ServerSocket( 5000, 100 );
		while(true) {
			for (int i = 0; i < 10; i++) {
				if (m[i]==null) {
					new Thread(m[i] = new Multi( m,server.accept(), displayArea, enterField)).start(); 
					counter++;	System.out.println(counter); 
					break;
				}
			}	
		}
	}
	static class Multi extends Thread implements ActionListener{
		protected Multi[] m;
		protected 	Socket connection;
		protected  JTextArea displayArea;
		protected  JTextField enterField;
		protected  PrintStream output = null;
		BufferedReader in = null;
		protected String message ="";
		public Multi(Multi[] m,Socket client, JTextArea a, JTextField t){
			this.m = m;
			this.connection = client;
			this.displayArea = a;
			this.enterField = t;
			this.enterField.addActionListener(this);

		}
		public void run(){
			this.runServer();
		}


		// set up and run server
		public void runServer()
		{
			// set up server to receive connections;
			// process connections
			try {
				// Step 1: Create a ServerSocket.			
				this.getStreams();


				// Step 3: Get input and output streams.


				// Step 4: Process connection.
				this.processConnection();
				//this.closeConnection();
				// Step 5: Close connection.
				//closeConnection();

			}

			// process EOFException when client closes connection
			catch ( EOFException eofException ) {
				System.out.println( "Client terminated connection" );
			}

			// process problems with I/O
			catch ( IOException ioException ) {
				ioException.printStackTrace();
			}
		}

		// wait for connection to arrive, then display connection info


		// get streams to send and receive data
		protected void getStreams() throws IOException
		{
			// set up output stream for objects
			output = new PrintStream(
					connection.getOutputStream(),true );

			// set up input stream for objects
			in = new BufferedReader(new InputStreamReader(connection.getInputStream()));

			displayArea.append( "\nGot I/O streams\n" );
		}

		// process connection with client
		protected void processConnection() 
		{
			// send connection successful message to client
			String message = "SERVER>>> Connection successful from : "+connection.getRemoteSocketAddress();
			displayArea.append( "\n" + message );
			//for (int i = 0; i < m.length; i++) {
//			if (m[i]!= null && i %2 ==0 && i>0) {m[i-1].output.writeObject( message ); m[i-1].output.flush(); break; }
//			else if (m[i]!= null && i % 2 > 0) {
//			m[i+1].output.writeObject( message ); m[i+1].output.flush(); break;}	
//			}
			//output.flush();
			// enable enterField so server user can send messages
			enterField.setEnabled( true );

			// process messages sent from client

			while(!connection.isConnected()){
				// read message and display it
				try {
					message = in.readLine();
					displayArea.append('\n'+message);
				//	for (int i = 0; i < m.length && m[i]!= null; i++) {
				//if ( i %2 ==0 && i>0) {m[i-2].output.writeObject( message ); m[i-2].output.flush(); break; }
				//else if (i % 2 != 0) {
				//m[i+2].output.writeObject( message ); m[i+2].output.flush(); break;}	
						
						//System.out.println("id "+m[i].getId()); 
						//System.out.println("name "+m[i].getName());
					//	}


					displayArea.setCaretPosition(
							displayArea.getText().length() );
				} 
				// catch problems reading from client 
				catch ( IOException ioException ) {
					 break;
				} 
			} this.closeConnection();

		}
		// close streams and socket
		protected void closeConnection() 
		{	
			displayArea.append("\n"+connection.getRemoteSocketAddress()+" terminated connection" );
				  
			try { 
				enterField.setText("");
				in.close(); 
				output.close();
				connection.close();
				for (int i = 0; i < m.length; i++) {
					if (m[i]==this){
						m[i].in.close(); 
						m[i].output.close();
						m[i].connection.close();
						m[i]=null;  
					}
				}
			} catch (IOException e) {
				System.out.println("Could not close socket");
			}  
		}
	// send message to client
	public void sendData( String message ) 
	{	
		// send object to client
		for (int i = 0; i < m.length; i++) {
			if(m[i]!= null && m[i].connection.isConnected()) { m[i].output.println("SERVER>>>"+message);}		
		}					
			displayArea.append("\nSERVER>>> "+message);
		// process problems sending object
	}	

	public void actionPerformed(ActionEvent arg0) {
		sendData(enterField.getText()); enterField.setText("");
	}
	}
} // end class Server